﻿using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

namespace TinyAsset
{
    public class UnityHttpClient : MonoSingleton<UnityHttpClient>
    {
        const int MAX_RUNNING_QUEUE_LENGTH = 10;

        float _lastUpdateTime;

        bool Busy => Time.realtimeSinceStartup - _lastUpdateTime >= 0.005f;

        LinkedList<UnityHttpRequest> Running = new LinkedList<UnityHttpRequest>();
        LinkedList<UnityHttpRequest> Completed = new LinkedList<UnityHttpRequest>();

        void Update()
        {
            _lastUpdateTime = Time.realtimeSinceStartup;

            LinkedListNode<UnityHttpRequest> first;

            while (Completed.First != null)
            {
                first = Completed.First;
                Completed.RemoveFirst();
                first.Value.NotifyCompletion();

                if (Busy)
                    return;
            }

            first = Running.First;
            for (int i = 0; first != null && i < MAX_RUNNING_QUEUE_LENGTH; i++)
            {
                var next = first.Next;
                first.Value.Update(Time.deltaTime, Time.unscaledDeltaTime);
                if (first.Value.IsCompleted)
                {
                    Running.Remove(first);
                    Completed.AddLast(first);
                }
                first = next;
            }
        }

        public UnityHttpRequest Get(string url)
        {
            UnityHttpRequest request = new UnityHttpRequest();
            request.
                SetUrl(url).
                SetMethod(UnityWebRequest.kHttpVerbGET).
                SetDownloadHandler(new DownloadHandlerBuffer()).
                CreateWebRequest();
            Running.AddLast(request);
            return request;
        }

        public UnityHttpRequest Head(string url)
        {
            UnityHttpRequest request = new UnityHttpRequest();
            request.SetUrl(url).
                    SetMethod(UnityWebRequest.kHttpVerbHEAD).
                    CreateWebRequest();
            Running.AddLast(request);
            return request;
        }


        public UnityHttpRequest Download(string url, string path)
        {
            UnityHttpRequest request = new UnityHttpRequest();
            request.SetUrl(url).
                    SetMethod(UnityWebRequest.kHttpVerbGET).
                    SetDownloadHandler(new DownloadHandlerFile(path)).
                    CreateWebRequest();
            Running.AddLast(request);
            return request;
        }
    }
}